
#pragma once

#if defined(__GNUC__) || defined(__MINGW32__) || defined(__MINGW__)
    #pragma GCC diagnostic push
    #pragma GCC diagnostic ignored "-Woverloaded-virtual"
    #pragma GCC diagnostic ignored "-Weffc++"
    #pragma GCC diagnostic ignored "-Wnon-virtual-dtor"


#endif

namespace tools{
    namespace variant_detail{

//--------------------------------------------------------------------------------------
//--------------------------------------------------------------------------------------
        template<class Iterator, class Directly> struct NextStep;

        template<class Iterator> struct NextStep<Iterator, DIRECT_NORMAL>: IStep
        {
            virtual void  Right() { ++mCur; }
            virtual void  Left()  { --mCur; }
        protected:
            Iterator mCur;
        };
        template<class Iterator> struct NextStep<Iterator, DIRECT_REVERSE>: IStep
        {
            virtual void  Right() { --mCur; }
            virtual void  Left()  { ++mCur; }
        protected:
            Iterator mCur;
        };
//--------------------------------------------------------------------------------------
        template<class T, class Iter, class Directly, int CATEGORY> struct BaseStep: NextStep<Iter, Directly>
        {
            typedef variant_detail::V::Str  Str;
            enum { eTYPE = Type2Enum<T>::eTYPE };

            bool operator==(const BaseStep& rhs)const { return this->mCur==rhs.mCur; }
            virtual bool operator==(const IStep& rhs)const
            {
                const BaseStep& r = static_cast<const BaseStep&>(rhs);
                return operator==(r);
            }

            void operator=(const BaseStep& rhs) { this->mCur = rhs.mCur; }

            virtual IStep& operator=(const IStep& rhs)
            {
                const BaseStep& r = static_cast<const BaseStep&>(rhs);
                operator=(r);
                return *this;
            }

            virtual const Str& GetKey()const
            {
                const void*const element = this->mCur.operator ->();
                return GetElement<T,CATEGORY>::GetKey(element);
            }
            virtual const Variant& GetVariant()const
            {
                const void*const element = this->mCur.operator ->();
                return GetElement<T, CATEGORY>::GetVariant(element);
            }
        };
//--------------------------------------------------------------------------------------

        template<class T, class Iter, class Directly,
                 int CATEGORY = Enum2Category< Type2Enum<T>::eTYPE >::eCATEGORY >
        struct Step: BaseStep<T, Iter, Directly,CATEGORY>
        {
            typedef BaseStep<T, Iter, Directly,CATEGORY> Parent;

            Step(const Iter& iterator) { this->mCur = iterator;  }

            Step(const Step& step)  { this->mCur = step.mCur; }

            Step& operator=(const Step& rhs)
            {
                Parent::operator =(rhs);
                return *this;
            }
        };
//--------------------------------------------------------------------------------------

    }//namespace variant_detail
}//namespace tools


#if defined(__GNUC__) || defined(__MINGW32__) || defined(__MINGW__)
    #pragma GCC diagnostic pop
#endif
